package com.jungle.client.control;


import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogPane;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.function.Consumer;

@Slf4j
public abstract class BasicDialog<T> implements Initializable {
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        log.info("init BasicDialog, url:{}", url);
    }

    /**
     * 显示一个对话框，用于显示特定的FXML界面，并允许用户进行交互
     *
     * @param fxmlUrl  FXML界面的URL，用于加载对话框的内容
     * @param title    对话框的标题
     * @param dataVo   传递给对话框的数据对象，用于在对话框中显示或编辑
     * @param consumer 一个消费型函数式接口，用于处理从对话框中返回的数据
     * @throws IOException 如果FXML加载失败
     */
    protected void showDialog(URL fxmlUrl, String title, T dataVo, Consumer<T> consumer) throws IOException {
        // 创建一个对话框实例
        Dialog<T> dialog = new Dialog<>();
        // 设置对话框的标题
        dialog.setTitle(title);

        // 获取对话框的对话面板
        DialogPane dialogPane = dialog.getDialogPane();
        // 设置对话框的按钮类型
        dialogPane.getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
        // 加载FXML文件，并将其作为对话框的内容
        BasicDialog<T> dialogController = loadFxml(fxmlUrl, dialogPane);
        // 将数据对象传递给对话框控制器，以供显示或编辑
        dialogController.loadData(dataVo);

        // 显示对话框，并等待用户响应只有当用户点击OK按钮时，才通过消费型接口处理返回的数据
        dialog.showAndWait().ifPresent(buttonType -> {
            if (buttonType == ButtonType.OK) {
                consumer.accept(dialogController.storeData());
            }
        });
    }

    /**
     * 加载并返回一个FXML文件定义的Node对象
     * 此方法用于根据给定的FXML资源URL，加载FXML文件，并返回文件定义的Node对象
     * 主要用于界面组件的加载，支持国际化
     *
     * @param url        FXML资源的URL，指定要加载的FXML文件
     * @param dialogPane 对话框的对话面板，用于设置对话框的内容
     * @return 返回一个BasicDialog<T>类型的对象，该对象包含了FXML文件中定义的Node对象
     * @throws IOException 如果读取FXML资源时发生I/O错误
     */
    private BasicDialog<T> loadFxml(URL url, DialogPane dialogPane) throws IOException {
        // 使用FXMLLoader加载指定的FXML资源
        FXMLLoader fxmlLoader = new FXMLLoader(url);
        // 设置资源捆绑，用于国际化
        fxmlLoader.setResources(com.jungle.client.FxApplication.bundle);
        // 加载FXML文件，并返回文件定义的界面组件树的根节点
        dialogPane.setContent(fxmlLoader.load());
        // 返回FXML文件中定义的控制器对象，该对象类型为BasicDialog<T>
        return fxmlLoader.getController();
    }

    protected abstract void loadData(T dataSetVo);

    protected abstract T storeData();
}
